《滑动到顶部悬浮功能条》源码学习整理笔记
来源:互联网 发布:数据库中insert的用法 编辑:程序博客网 时间:2024/06/05 23:41
项目源码地址:https://git.oschina.net/steve/HoveringScroll
实现原理解析:
我这里使用了不同的颜色,将后面会讲解到的几个布局标注了出来。
这里有几个对象A布局、B布局、C布局需要事先说明一下:
A布局示意图:
B布局示意图:
C布局示意图:
1.Activity初始化时的状态,此时C布局在B布局上:
2.当向上滑动屏幕,布局B也会随着滚动布局向上滚动:
3.当向上滑动的距离超过了开始时顶部布局的高度H时,本来在B上的子布局C就会被移除,然后加到A布局上:
代码实现部分:
// 自定义ScrollView滑动监听,获取实时的Y轴滑动距离 @Override public void onScroll(int scrollY) { Log.d("guxuewu", "scrollY=>" + scrollY); // 如果滑动的距离大于等于了顶部布局的高度H if (scrollY >= searchLayoutTop) { // 并且固定布局C的父布局不是A布局 if (hoveringLayout.getParent() != search01) { // B布局移除布局C search02.removeView(hoveringLayout); // A加入布局C search01.addView(hoveringLayout); } } // 如果滑动距离小于了顶部布局的高度 else { // 并且固定布局C的父布局不是B布局 if (hoveringLayout.getParent() != search02) { // A布局移除固定布局C search01.removeView(hoveringLayout); // B加入固定布局C search02.addView(hoveringLayout); } } }
代码详解
HoveringScrollSampleActivity.java
public class HoveringScrollSampleActivity extends Activity implements OnScrollListener{ // 自定义的ScrollView private HoveringScrollview hoveringScrollview; // 顶部布局的高度 private int searchLayoutTop; // 顶部布局 private RelativeLayout rlayout; // 中间固定条的布局 private LinearLayout hoveringLayout; // 不跟随ScrollView移动的父布局 private LinearLayout search01; // 跟随ScrollView移动的父布局 // Search01的布局高度要和search02的设置一样,这样看起来就不会有替换的感觉 private LinearLayout search02; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_samples); initViews(); } private void initViews() { hoveringLayout = (LinearLayout)findViewById(R.id.hoveringLayout); hoveringScrollview = (HoveringScrollview)findViewById(R.id.hoveringScrollview); search01 = (LinearLayout)findViewById(R.id.search01); search02 = (LinearLayout)findViewById(R.id.search02); rlayout = (RelativeLayout)findViewById(R.id.rlayout); hoveringScrollview.setOnScrollListener(this); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); // 每次启动,设置顶部布局的高度 if (hasFocus) { searchLayoutTop = rlayout.getBottom(); } } // 自定义ScrollView滑动监听,获取实时的Y轴滑动距离 @Override public void onScroll(int scrollY) { Log.d("guxuewu", "scrollY=>" + scrollY); // 如果滑动的距离大于等于了顶部布局的高度H if (scrollY >= searchLayoutTop) { // 并且固定布局C的父布局不是A布局 if (hoveringLayout.getParent() != search01) { // B布局移除布局C search02.removeView(hoveringLayout); // A加入布局C search01.addView(hoveringLayout); } } // 如果滑动距离小于了顶部布局的高度 else { // 并且固定布局C的父布局不是B布局 if (hoveringLayout.getParent() != search02) { // A布局移除固定布局C search01.removeView(hoveringLayout); // B加入固定布局C search02.addView(hoveringLayout); } } } // 点击事件监听 public void clickListenerMe(View view) { if (view.getId() == R.id.btnQiaBuy) { Toast.makeText(this, "抢购成功", Toast.LENGTH_SHORT).show(); } }}
HoveringScrollview.java
public class HoveringScrollview extends ScrollView{ // 滚动监听器 private OnScrollListener onScrollListener; /** * 主要是用在用户手指离开本view,本view还在继续滑动,我们用来保存Y的距离,然后做比较 */ private int lastScrollY; public HoveringScrollview(Context context, AttributeSet attrs) { super(context, attrs); } /** * 设置滚动监听接口 */ public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } /** * 用于用户手指离开MyScrollView的时候获取MyScrollView滚动的Y距离,然后回调给onScroll方法中 */ @SuppressLint("HandlerLeak") private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { int scrollY = HoveringScrollview.this.getScrollY(); // 此时的距离和记录下的距离不相等,在隔6毫秒给handler发送消息 if (lastScrollY != scrollY) { lastScrollY = scrollY; // 相当于开启了一个无线循环的消息机制 handler.sendMessageDelayed(handler.obtainMessage(), 20); } if (onScrollListener != null) { onScrollListener.onScroll(scrollY); } }; }; @SuppressLint("ClickableViewAccessibility") public boolean onTouchEvent(MotionEvent ev) { // 当用户的手在HoveringScrollview上面的时候, // 直接将HoveringScrollview滑动的Y方向距离回调给onScroll方法中, if (onScrollListener != null) { onScrollListener.onScroll(lastScrollY = this.getScrollY()); } switch (ev.getAction()) { // 当用户抬起手的时候,HoveringScrollview可能还在滑动, // 所以当用户抬起手我们隔6毫秒给handler发送消息, // 在handler处理 HoveringScrollview滑动的距离 case MotionEvent.ACTION_UP: handler.sendMessageDelayed(handler.obtainMessage(), 20); break; } return super.onTouchEvent(ev); }; /** * 滚动的回调接口 */ public interface OnScrollListener { /** * 回调方法, 返回本view滑动的Y方向距离 */ public void onScroll(int scrollY); }}
布局文件activity_samples.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" > <com.steve.hovering.samples.HoveringScrollview android:id="@+id/hoveringScrollview" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- 套在ScrollView中的唯一父布局 --> <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="TOP信息占位\nTOP信息\nTOP信息\nTOP信息占位" android:textColor="#d19275" android:textSize="30sp" /> </RelativeLayout> <!-- 跟随ScrollView移动的父布局 --> <LinearLayout android:id="@+id/search02" android:layout_width="match_parent" android:layout_height="70dp" android:background="@android:color/holo_green_light" > <!-- 这个悬浮条必须是固定高度 --> <!-- android:background="#A8A8A8" --> <LinearLayout android:id="@+id/hoveringLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:padding="10dp" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="¥188\r\n原价:¥399" android:textColor="#FF7F00" /> <Button android:id="@+id/btnQiaBuy" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="#FF7F00" android:onClick="clickListenerMe" android:padding="10dp" android:text="立即抢购" android:textColor="#FFFFFF" /> </LinearLayout> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="1测试内容\n2测试内容\n3测试内容\n4测试内容\n5测试内容\n6测试内容\n7测试内容\n8测试内容\n9测试内容\n10测试内容\n11测试内容\n12测试内容\n13测试内容\n14测试内容\n15测试内容\n16测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n27测试内容" android:textSize="40sp" /> </LinearLayout> </com.steve.hovering.samples.HoveringScrollview> <!-- 固定不动的用来装固定布局的父布局 --> <LinearLayout android:id="@+id/search01" android:layout_width="match_parent" android:layout_height="70dp" android:background="@android:color/darker_gray" android:orientation="vertical" > </LinearLayout></RelativeLayout>
最终效果
学习心得
学习大神的代码总能收益颇多,之前也一直想研究这个效果怎么做出来,无意在论坛看到这个源码分享,便迫不及待拿来细细研究。
研究后发现自己原来好多实现想法想复杂了,原来这么简单其实就可以实现这个效果。
所以我们还是得敢于尝试,尝试用最简单的方法去实现想要的效果。
1 0
- 《滑动到顶部悬浮功能条》源码学习整理笔记
- 安卓学习笔记---android RecyclerView首字母悬浮在顶部,滑动删除
- 高仿网易新闻顶部滑动条效果 (源码)
- jq和js滑动条到顶部距离获取
- Android 滑动组件悬浮固定在顶部
- 【学习笔记】实现顶部滚动条
- 安卓学习笔记---实现两个ListView或者GridView在Scrollview中同时滑动,实现ScrollView滑动到顶部
- RecyclerView实现顶部悬浮条效果 自定义!
- Android笔记之判断ListView滑动到顶部或底部
- Anddroid ExpandableListView 实现父Item悬浮在顶部不动,子Item滑动显示,直到下一个父Item滑动到顶部的效果
- 悬浮怪物血条功能
- jquery 滑动到顶部效果
- 12.PullToRefresh滑动到顶部
- ListView滑动到顶部停靠
- listview滑动到顶部再往下拉的时候有条缝隙
- ScrollView向上滑动滑动到顶部悬停
- Android ScrollView向上滑动控件顶部悬浮效果实现
- Android ScrollView向上滑动控件顶部悬浮效果实现
- zeroDateTimeBehavior=convertToNull
- sql 本日\本周\本月统计
- 完整的Ajax实例
- Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
- SQL常用查询语句
- 《滑动到顶部悬浮功能条》源码学习整理笔记
- MVC kendo Grid EditorTemplate
- coreData
- Razor模板引擎工作原理及怎么调用外部方法演示
- Java并发编程:Thread类的使用
- hdu 4389 X mod f(x) 数位dp
- static 关键字
- Java总结杂记
- SCCM 2012安装教程(Part2)