Android中使用ScrollView指定view的顶部悬停效果
因项目中的需要实现scrollview顶部的悬停,也不是太难便自己实现功能,话不多说,先上效果图
红色text一到顶上便会悬浮在上面,不会跟随scrollview的滑动而上滑。
原理:
原理其实很简单就是对view的gone和visible,写两个相同的要置顶的view,一个设置为gone,一个为visible,当可见的view超出屏幕范围的时候,将不可以的view设置为visible,不可见的view 与scrollview要同级,这样滑动的时候不会影响到view的位置。
直接上代码
<?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"> <com.lanmai.observablescrollview xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent" > <relativelayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <linearlayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 中间就是填充的view就不写了--> <!--指定要置顶的view--> <textview android:id="@+id/specific_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="text" android:textsize="40sp"/> <textview android:layout_width="match_parent" android:layout_height="200dp" android:background="@android:color/darker_gray" android:gravity="center" android:text="text" android:textsize="40sp"/> </linearlayout> </relativelayout> </com.lanmai.observablescrollview> <!--指定要置顶的相同的view visibility设置为gone --> <textview android:id="@+id/specific_text_view_gone" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="text" android:textsize="40sp" android:visibility="gone"/> </relativelayout>
接下来要重写scrollview,为什么要重写scrollview,scrollview的滑动监听事件setonscrollchangelistener 这个方法是在6.0以上才能用的。为了考虑低版本的的需求,要重写scrollview把接口开放出来。
重写scrollview
public class observablescrollview extends scrollview { private scrollviewlistener scrollviewlistener = null; public observablescrollview(context context) { super(context); } public observablescrollview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); } public observablescrollview(context context, attributeset attrs) { super(context, attrs); } public void setscrollviewlistener(scrollviewlistener scrollviewlistener) { this.scrollviewlistener = scrollviewlistener; } @override protected void onscrollchanged(int x, int y, int oldx, int oldy) { super.onscrollchanged(x, y, oldx, oldy); if (scrollviewlistener != null) { scrollviewlistener.onscrollchanged(this, x, y, oldx, oldy); } } public interface scrollviewlistener { void onscrollchanged(scrollview scrollview, int x, int y, int oldx, int oldy); } }
我把重写的scrollview命名为observablescrollview,重写三个构造方法,都是换汤不换药的作法,这里就不赘述。 最重要的是重写onscrollchanged这个方法,如何把滑动监听事件开放出去呢,其实也就是写一个监听回调,参数和onscrollchanged里面的的参数一样就可以了,当然主要不是用到这些参数,只是为了判断scrollview的滑动事件,参数对于这个功并不是很重要。那这样,一个简单的自定义就写好了scrollview
如何去用?
用法也是挺简单的,直接上代码
@override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_scroll_view); mtextview = ((textview) findviewbyid(r.id.specific_text_view)); mscrollview = ((observablescrollview) findviewbyid(r.id.scrollview)); mvisibletextview = ((textview) findviewbyid(r.id.specific_text_view_gone)); mtextview.setonclicklistener(this); mscrollview.setscrollviewlistener(this); }
这里oncreate方法里面的,也简单,拿到view 并且设置监听事件,当然,这里多实现了一个点击view置顶的功能,监听设置好以后,实现相应的接,接下来就是重头戏了
@override public void onscrollchanged(scrollview scrollview, int x, int y, int oldx, int oldy) { int[] location = new int[2]; mtextview.getlocationonscreen(location); int xposition = location[0]; int yposition = location[1]; log.d("scrollviewactivity", "yposition:" + yposition); int statusbarheight = getstatusbarheight(); log.d("scrollviewactivity", "statusbarheight:" + statusbarheight); if (yposition <= statusbarheight) { mvisibletextview.setvisibility(view.visible); } else { mvisibletextview.setvisibility(view.gone); } }
onscrollchanged这个方法就是自己写的监听回调,里面的参数就是scrollview滑动的时候回调出来的,里面的参数并不用去关心
int[] location = new int[2]; mtextview.getlocationonscreen(location); int xposition = location[0]; int yposition = location[1]; /* mtextview就是要悬浮的view,getlocationonscreen(location)这个方法就是拿到view在屏幕中的位置 ,传入一个数组,最后得到的yposition就是view在屏幕中的高度,这里面调用了native层的实现方式,所以数组能直接附上值*/ // 值得注意的是,拿到的这个高度还包括状态栏的高度。只要减掉就可以了,状态栏的高度获取获取附上代码: public int getstatusbarheight() { int result = 0; int resourceid = getresources().getidentifier("status_bar_height", "dimen", "android"); if (resourceid > 0) { result = getresources().getdimensionpixelsize(resourceid); } return result; } int statusbarheight = getstatusbarheight(); log.d("scrollviewactivity", "statusbarheight:" + statusbarheight); 通过获取到的状态栏高度,如果小于状态栏的高度就表示已经滑出屏幕了,将要置顶的view设置为visibvle否则设置为gone if (yposition <= statusbarheight) { mvisibletextview.setvisibility(view.visible); } else { mvisibletextview.setvisibility(view.gone); }
这样scrollview的悬浮置顶的功能就实现了,这里我也给出点击view置顶的代码
@override public void onclick(view v) { int[] location = new int[2]; v.getlocationonscreen(location); int x = location[0]; int y = location[1]; mscrollview.scrollby(0, location[1] - getstatusbarheight()); }
当然要缓慢的滑动过程用smoothscrollby替代就可以了
结论:
实现这种效果,找对了思路就可以很容易的写出来了,这是一种比较简单的实现方式了,源码我就不贴出来了,基本已经都在了。
以上所述是小编给大家介绍的android中使用scrollview指定view的悬停效果,希望对大家有所帮助。。。