Android ScrollView向上滑动控件顶部悬浮效果实现

【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中,有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。

本文的方法是通过addView和removeView来实现的。

一、首先让ScrollView实现滚动监听:

[java]  view plain  copy
  1. package com.willen.topFloatDemo;  
  2.   
  3. import android.content.Context;  
  4. import android.os.Handler;  
  5. import android.util.AttributeSet;  
  6. import android.view.MotionEvent;  
  7. import android.widget.ScrollView;  
  8.   
  9. /* 
  10.  * ScrollView并没有实现滚动监听,所以我们必须自行实现对ScrollView的监听, 
  11.  * 我们很自然的想到在onTouchEvent()方法中实现对滚动Y轴进行监听 
  12.  * ScrollView的滚动Y值进行监听 
  13.  */  
  14. public class MyScrollView extends ScrollView {  
  15.     private OnScrollListener onScrollListener;    
  16.     /**  
  17.      * 主要是用在用户手指离开MyScrollView,MyScrollView还在继续滑动,我们用来保存Y的距离,然后做比较  
  18.      */    
  19.     private int lastScrollY;  
  20.       
  21.     public MyScrollView(Context context) {  
  22.         super(context, null);  
  23.     }  
  24.     public MyScrollView(Context context, AttributeSet attrs) {  
  25.         super(context, attrs, 0);  
  26.     }  
  27.     public MyScrollView(Context context, AttributeSet attrs, int defStyle) {  
  28.         super(context, attrs, defStyle);  
  29.     }  
  30.     /**  
  31.      * 设置滚动接口  
  32.      * @param onScrollListener  
  33.      */  
  34.     public void setOnScrollListener(OnScrollListener onScrollListener){  
  35.         this.onScrollListener = onScrollListener;  
  36.     }  
  37.     /**  
  38.      * 用于用户手指离开MyScrollView的时候获取MyScrollView滚动的Y距离,然后回调给onScroll方法中  
  39.      */    
  40.     private Handler handler = new Handler() {    
  41.     
  42.         public void handleMessage(android.os.Message msg) {    
  43.             int scrollY = MyScrollView.this.getScrollY();    
  44.                 
  45.             //此时的距离和记录下的距离不相等,在隔5毫秒给handler发送消息    
  46.             if(lastScrollY != scrollY){    
  47.                 lastScrollY = scrollY;    
  48.                 handler.sendMessageDelayed(handler.obtainMessage(), 5);      
  49.             }    
  50.             if(onScrollListener != null){    
  51.                 onScrollListener.onScroll(scrollY);    
  52.             }    
  53.                 
  54.         };    
  55.     
  56.     };   
  57.     /**  
  58.      * 重写onTouchEvent, 当用户的手在MyScrollView上面的时候,  
  59.      * 直接将MyScrollView滑动的Y方向距离回调给onScroll方法中,当用户抬起手的时候,  
  60.      * MyScrollView可能还在滑动,所以当用户抬起手我们隔5毫秒给handler发送消息,在handler处理  
  61.      * MyScrollView滑动的距离  
  62.      */   
  63.     @Override  
  64.     public boolean onTouchEvent(MotionEvent ev) {  
  65.         if(onScrollListener != null){    
  66.             onScrollListener.onScroll(lastScrollY = this.getScrollY());    
  67.         }    
  68.         switch(ev.getAction()){    
  69.         case MotionEvent.ACTION_UP:    
  70.              handler.sendMessageDelayed(handler.obtainMessage(), 20);      
  71.             break;    
  72.         }    
  73.         return super.onTouchEvent(ev);  
  74.     }  
  75.   
  76.     /**  
  77.      * 滚动的回调接口  
  78.      */    
  79.     public interface OnScrollListener{    
  80.         /**  
  81.          * 回调方法, 返回MyScrollView滑动的Y方向距离  
  82.          */    
  83.         public void onScroll(int scrollY);    
  84.     }  
  85. }  

二、定义简单布局

[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:id="@+id/container"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <com.willen.topFloatDemo.MyScrollView  
  9.         android:id="@+id/myScrollView"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent" >  
  12.   
  13.         <LinearLayout  
  14.             android:layout_width="match_parent"  
  15.             android:layout_height="wrap_content"  
  16.             android:orientation="vertical" >  
  17.   
  18.             <RelativeLayout  
  19.                 android:id="@+id/rlayout"  
  20.                 android:layout_width="wrap_content"  
  21.                 android:layout_height="wrap_content"  
  22.                 android:layout_gravity="center_horizontal" >  
  23.   
  24.                 <TextView  
  25.                     android:id="@+id/tv"  
  26.                     android:layout_width="wrap_content"  
  27.                     android:layout_height="wrap_content"  
  28.                     android:gravity="center_vertical"  
  29.                     android:text="顶部信息\n顶部信息\n顶部信息\n顶部信息"  
  30.                     android:textSize="40dp" />  
  31.             </RelativeLayout>  
  32.   
  33.             <LinearLayout  
  34.                 android:id="@+id/search02"  
  35.                 android:layout_width="match_parent"  
  36.                 android:layout_height="40dip"  
  37.                 android:orientation="vertical" >  
  38.   
  39.                 <EditText  
  40.                     android:id="@+id/search_edit"  
  41.                     android:layout_width="match_parent"  
  42.                     android:layout_height="40dip"  
  43.                     android:background="@drawable/bg_edittext"  
  44.                     android:hint="请输入..."  
  45.                     android:padding="5dip"  
  46.                     android:singleLine="true"  
  47.                     android:textColorHint="#AAAAAA"  
  48.                     android:textSize="15dip" />  
  49.             </LinearLayout>  
  50.   
  51.             <TextView  
  52.                 android:layout_width="match_parent"  
  53.                 android:layout_height="wrap_content"  
  54.                 android:gravity="center_horizontal"  
  55.                 android:text="测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容"  
  56.                 android:textSize="40dp" />  
  57.         </LinearLayout>  
  58.     </com.willen.topFloatDemo.MyScrollView>  
  59.   
  60.     <LinearLayout  
  61.         android:id="@+id/search01"  
  62.         android:layout_width="match_parent"  
  63.         android:layout_height="40dip"  
  64.         android:orientation="vertical" >  
  65.     </LinearLayout>  
  66.   
  67. </RelativeLayout>  

三、MainActivity

[java]  view plain  copy
  1. package com.willen.topFloatDemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.EditText;  
  6. import android.widget.LinearLayout;  
  7. import android.widget.RelativeLayout;  
  8.   
  9. import com.willen.topFloatDemo.MyScrollView.OnScrollListener;  
  10.   
  11. public class MainActivity extends Activity implements OnScrollListener{  
  12.     private EditText search_edit;  
  13.     private MyScrollView myScrollView;  
  14.     private int searchLayoutTop;  
  15.       
  16.     LinearLayout search01,search02;  
  17.     RelativeLayout rlayout;  
  18.       
  19.     @Override  
  20.     protected void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.activity_main);  
  23.         //初始化控件  
  24.         init();  
  25.     }  
  26.   
  27.     private void init() {  
  28.         search_edit = (EditText)findViewById(R.id.search_edit);  
  29.         myScrollView = (MyScrollView)findViewById(R.id.myScrollView);  
  30.         search01 = (LinearLayout)findViewById(R.id.search01);  
  31.         search02 = (LinearLayout)findViewById(R.id.search02);  
  32.         rlayout = (RelativeLayout)findViewById(R.id.rlayout);  
  33.         myScrollView.setOnScrollListener(this);    
  34.           
  35.     }  
  36.   
  37.     @Override  
  38.     public void onWindowFocusChanged(boolean hasFocus) {  
  39.         super.onWindowFocusChanged(hasFocus);      
  40.         if(hasFocus){    
  41.             searchLayoutTop = rlayout.getBottom();//获取searchLayout的顶部位置  
  42.         }  
  43.     }  
  44.   
  45.     //监听滚动Y值变化,通过addView和removeView来实现悬停效果  
  46.     @Override  
  47.     public void onScroll(int scrollY) {  
  48.         if(scrollY >= searchLayoutTop){    
  49.             if (search_edit.getParent()!=search01) {  
  50.                 search02.removeView(search_edit);  
  51.                 search01.addView(search_edit);  
  52.             }  
  53.         }else{  
  54.             if (search_edit.getParent()!=search02) {  
  55.                 search01.removeView(search_edit);  
  56.                 search02.addView(search_edit);  
  57.             }  
  58.         }  
  59.     }  
  60. }  

代码中均有注释,应该不用再多解释了。

本文源码下载:http://download.csdn.net/detail/viviwen123/7989349

你可能感兴趣的:(ListView,顶部悬浮)