上滑ScrollView,实现控件顶部悬浮
因为看到网上的比较复杂,所以自己写了这篇,希望能够足够简单。
先看效果图,是不是你需要的:
不论怎么滑动屏幕内容,当蓝色部分到达顶部时,便会一直会显示在顶部。
实现原理:
顶部1,顶部2布局需要完全一样,初始化时顶部1不显示,为Gone。
当顶部2向上滑动到屏幕顶端时,设置顶部1可见,由于顶部1不包含在ScrollVIew里面,所以会一直存在,不会被滑动;
而向下滑时,当顶部2到达屏幕顶端,隐藏顶部1,显示顶部2即可。
所以实现关键步骤是:
判断顶部2是否滑动到了顶部,也就是标题栏之下。
先看布局,很简单:
布局和原理里面一致:顶部1,ScrollView 就没了。
只是有一个自定义的ScrollView,这个是重点,在代码里面讲,布局也没什么。
记得顶部1不再ScrollView里面,二顶部2在ScrollView里面哦~
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="runa.sometest.slidingstop.SlidingActivity">
<TextView
android:id="@+id/top1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="this蓝色部分滑动到顶部,悬浮"
android:textColor="@android:color/white"
android:gravity="center"
android:visibility="gone"
android:background="#006699"/>
<com.sometest.slidingstop.MyScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitXY"
android:src="@drawable/img1"/>
<TextView
android:id="@+id/top2"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="this蓝色部分滑动到顶部,悬浮"
android:textColor="@android:color/white"
android:gravity="center"
android:background="#006699"/>
<TextView
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="2000dp"
android:text="\n这里只是一个Textview,高度2000\n1\n2\n3\n4\n5" />
</LinearLayout>
</com.sometest.slidingstop.MyScrollView>
</LinearLayout>
接下来就看自定义的ScrollView:
这里面关键的就是onScrollChanged这个方法,实现了ScrollView滑动距离的监听。
只用看有注释的地方。
public class MyScrollView extends ScrollView { private static StopCall stopCall; //ScrollView向上滑动到顶部的距离 private int upH; public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); //赋值:300很重要,这个值是顶部2上面的高度,也就是本例中图片的高度 upH = dpTopx(300);//单位是dppublic MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public static void setCallback(StopCall c){ stopCall =c ; }
/**
* 关键部分在这里,测量当前ScrollView滑动的距离
* 其中t就是,单位是px哦,不是dp
* stopCall是一个接口,是为了在Activity中实现设置顶部1/2可不可见
*/
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if(t>upH){//如果滑动距离>本例中图片高度 stopCall.stopSlide(true);//设置顶部1可见,顶部2不可见 }else{//否则 stopCall.stopSlide(false);//设置顶部1不可见,顶部2可见 } } /** * F: 将dp转成为px */ private int dpTopx( int dpValue) { final float scale = this.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }}
最后看一下Activity:
/**
* 接口实现,可不可就
*/
public void stopSlide(boolean isStop){
if(isStop){
t1.setVisibility(View.VISIBLE);
t2.setVisibility(View.GONE);
}else {
t2.setVisibility(View.VISIBLE);
t1.setVisibility(View.GONE);
}
}
接口:
public interface StopCall {
public void stopSlide(boolean isStop);
}
总结;
其实最最关键的点就只有一个:测量当前ScrollView滑动的距离,如果顶部2到达了顶部,那么设置顶部1可见。否则不可见。
-----------------------------
因为工程不是单独的,里面还有很多其它内容,所以就不上传了,代码很简单,都贴在本文里面了,关键的关键是看懂实现原理。