本文参考了:《上滑停靠顶端的悬浮框》的代码,在此表示感谢。【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中,有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。
本文的方法是通过addView和removeView来实现的。
一、首先让ScrollView实现滚动监听:
[java]
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. 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. this.getScrollY());
67. }
68. switch(ev.getAction()){
69. case MotionEvent.ACTION_UP:
70. 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]
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]
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. this);
34.
35. }
36.
37. @Override
38. public void onWindowFocusChanged(boolean hasFocus) {
39. super.onWindowFocusChanged(hasFocus);
40. if(hasFocus){
41. //获取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. }
代码中均有注释,应该不用再多解释了。
本文源码下载:javascript:void(0)