Android ScrollView 上推至顶部使控件悬浮

来源:互联网 发布:深夜前的五分钟知乎 编辑:程序博客网 时间:2024/05/17 03:00

今天项目中有用到一个需求:上推页面使得某个控件到了顶部之后就一直悬浮在顶部,下拉后滑动到控件原始位置时,控件随页面一起下滑,搞了一段时间也算是搞出来了,直接上代码吧:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:id="@+id/container"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >    <com.willen.topFloatDemo.MyScrollView         android:id="@+id/myScrollView"         android:layout_width="match_parent"         android:layout_height="match_parent" >        <LinearLayout             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:orientation="vertical" >            <RelativeLayout                 android:id="@+id/rlayout"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_gravity="center_horizontal" >                <TextView                     android:id="@+id/tv"                     android:layout_width="wrap_content"                     android:layout_height="wrap_content"                     android:gravity="center_vertical"                     android:text="顶部信息\n顶部信息\n顶部信息\n顶部信息"                     android:textSize="40dp" />             </RelativeLayout>            <LinearLayout                 android:id="@+id/search02"                 android:layout_width="match_parent"                 android:layout_height="40dip"                 android:orientation="vertical" >                <EditText                     android:id="@+id/search_edit"                     android:layout_width="match_parent"                     android:layout_height="40dip"                     android:background="@drawable/bg_edittext"                     android:hint="请输入..."                     android:padding="5dip"                     android:singleLine="true"                     android:textColorHint="#AAAAAA"                     android:textSize="15dip" />             </LinearLayout>            <TextView                 android:layout_width="match_parent"                 android:layout_height="wrap_content"                 android:gravity="center_horizontal"                 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测试内容"                 android:textSize="40dp" />         </LinearLayout>     </com.willen.topFloatDemo.MyScrollView>
一个工具类:MyScrollView.java,大家可以直接使用

import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView;/* * ScrollView并没有实现滚动监听,所以我们必须自行实现对ScrollView的监听, * 我们很自然的想到在onTouchEvent()方法中实现对滚动Y轴进行监听 * ScrollView的滚动Y值进行监听 */ public class MyScrollView extends ScrollView {     private OnScrollListener onScrollListener;      /**      * 主要是用在用户手指离开MyScrollView,MyScrollView还在继续滑动,我们用来保存Y的距离,然后做比较      */      private int lastScrollY;         public MyScrollView(Context context) {         super(context, null);     }     public MyScrollView(Context context, AttributeSet attrs) {         super(context, attrs, 0);     }     public MyScrollView(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);     }     /**      * 设置滚动接口      * @param onScrollListener      */     public void setOnScrollListener(OnScrollListener onScrollListener){         this.onScrollListener = onScrollListener;     }     /**      * 用于用户手指离开MyScrollView的时候获取MyScrollView滚动的Y距离,然后回调给onScroll方法中      */      private Handler handler = new Handler() {            public void handleMessage(android.os.Message msg) {              int scrollY = MyScrollView.this.getScrollY();                            //此时的距离和记录下的距离不相等,在隔5毫秒给handler发送消息              if(lastScrollY != scrollY){                  lastScrollY = scrollY;                  handler.sendMessageDelayed(handler.obtainMessage(), 5);                }              if(onScrollListener != null){                  onScrollListener.onScroll(scrollY);              }                        };        };     /**      * 重写onTouchEvent, 当用户的手在MyScrollView上面的时候,      * 直接将MyScrollView滑动的Y方向距离回调给onScroll方法中,当用户抬起手的时候,      * MyScrollView可能还在滑动,所以当用户抬起手我们隔5毫秒给handler发送消息,在handler处理      * MyScrollView滑动的距离      */     @Override     public boolean onTouchEvent(MotionEvent ev) {         if(onScrollListener != null){              onScrollListener.onScroll(lastScrollY = this.getScrollY());          }          switch(ev.getAction()){          case MotionEvent.ACTION_UP:               handler.sendMessageDelayed(handler.obtainMessage(), 20);                break;          }          return super.onTouchEvent(ev);     }    /**      * 滚动的回调接口      */      public interface OnScrollListener{          /**          * 回调方法, 返回MyScrollView滑动的Y方向距离          */          public void onScroll(int scrollY);      } } 
主页面Activity

import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout;import com.willen.topFloatDemo.MyScrollView.OnScrollListener;public class MainActivity extends Activity implements OnScrollListener{     private EditText search_edit;     private MyScrollView myScrollView;     private int searchLayoutTop;         LinearLayout search01,search02;     RelativeLayout rlayout;         @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         //初始化控件         init();     }    private void init() {         search_edit = (EditText)findViewById(R.id.search_edit);         myScrollView = (MyScrollView)findViewById(R.id.myScrollView);         search01 = (LinearLayout)findViewById(R.id.search01);         search02 = (LinearLayout)findViewById(R.id.search02);         rlayout = (RelativeLayout)findViewById(R.id.rlayout);         myScrollView.setOnScrollListener(this);              }    @Override     public void onWindowFocusChanged(boolean hasFocus) {         super.onWindowFocusChanged(hasFocus);            if(hasFocus){              searchLayoutTop = rlayout.getBottom();//获取searchLayout的顶部位置         }     }    //监听滚动Y值变化,通过addView和removeView来实现悬停效果     @Override     public void onScroll(int scrollY) {         Log.e("dssdff", searchLayoutTop +"\\" +scrollY );         if(scrollY >= searchLayoutTop){              if (search_edit.getParent()!=search01) {                 Log.e("dssdff", "1");                 search02.removeView(search_edit);                 search01.addView(search_edit);             }         }else{             if (search_edit.getParent()!=search02) {                 Log.e("dssdff", "2");                 search01.removeView(search_edit);                 search02.addView(search_edit);             }         }     } }




0 0