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的悬停效果,希望对大家有所帮助。。。

时间: 2024-07-29 10:49:19

Android中使用ScrollView指定view的顶部悬停效果的相关文章

Android中自定义ScrollView代码实例_Android

Android中的ScrollView其实是很简陋的,竟然没有和ListView一样的可以设置一个OnScrollListener,不过没有关系,我们可以继承自ScrollView来自定义一个.废话不多说,直接上代码: 复制代码 代码如下: public class ObservableScrollView extends ScrollView {     public ObservableScrollView(Context context) {         super(context);

Android中我继承了View,为什么访问不了View中的protected属性,例如Scrollx什么的~

问题描述 Android中我继承了View,为什么访问不了View中的protected属性,例如Scrollx什么的~ 问题补充:renpeng301 写道 解决方案 BubbleTextView.Java 这个文件出错么?调试launcher的文章[url]http://gqdy365.iteye.com/blog/763543[/url]解决方案二:引用主要我是从code.google上下的系统Launcher的源代码~那我怎么才能把它弄好~~ 用Scrollx的get方法.解决方案三:查

Android中自定义ScrollView代码实例

Android中的ScrollView其实是很简陋的,竟然没有和ListView一样的可以设置一个OnScrollListener,不过没有关系,我们可以继承自ScrollView来自定义一个.废话不多说,直接上代码: 复制代码 代码如下: public class ObservableScrollView extends ScrollView { public ObservableScrollView(Context context) {         super(context);    

Android中使用TabHost 与 Fragment 制作页面切换效果_Android

三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义页面切换的效果:切换页面时,当前页面滑出,目标页面滑入.这是2个不同的动画设定动画时要区分对待 import android.content.Context; import android.util.AttributeSet; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import

Android中使用TabHost 与 Fragment 制作页面切换效果

三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义页面切换的效果:切换页面时,当前页面滑出,目标页面滑入.这是2个不同的动画设定动画时要区分对待 import android.content.Context; import android.util.AttributeSet; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import

Android 中 TabHost与ViewPager结合实现首页导航效果_Android

今天发的是TabHost结合ViewPager实现首页底部导航的效果,虽然说网上有很多这样的Demo,不过呢,我还是要把自己练习写的发出来,没错!就是这么任性: 先上效果图,如下: 代码里面有注释,就不过多解释了,说几点需要注意的问题 1:TabHost .TabWidget.FrameLayout一定添加id这个属性,否则会报错 android:id="@android:id/tabhost" android:id="@android:id/tabcontent"

android 中如何去掉listView自带的回弹效果

问题描述 android 中如何去掉listView自带的回弹效果 android 中做listView的下拉刷新和上拉加载更多!魅族,还有其它的产商的手机下啦与自带的回弹 效果怎么去掉,下啦涮新怪怪的 解决方案 listview有属性可以设置的:listView.setOverScrollMode(View.OVER_SCROLL_NEVER); 解决方案二: 在xml中,listView的一个属性 android:overScrollMode="never" 在代码中 mListV

Android中ListView + CheckBox实现单选、多选效果

还是先来看看是不是你想要的效果: 不废话,直接上代码,很简单,代码里都有注释 1 单选 public class SingleActivity extends AppCompatActivity { private ListView listView; private ArrayList<String> groups; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInsta

Android 中从屏幕左下角弹出Dialog动画效果的实现代码

MainActivity代码: import android.app.Dialog; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import androi