粘性的ListView和ScrollView

 

粘性的ListView和ScrollView 

先看一下效果

ListView的

未知
ListView的header上面 有一个粘性的view 在滚动上去时候 他可以固定住,滑动下去之后 又下来了 


ScrollView也有这样的效果,

未知

 

这个是怎么实现的呢?其实他们原理都是一样的!

之前总感觉是把这个view remove掉之后 然后再添加到其他ViewGroup上
后来看了StickyHeaderListView(https://www.jianshu.com/p/3bf26722c489)项目的源码 之后,明白了
这都是障眼法 其实很简单!这个项目 看着很乱 添加了很多东西 加了好几个HeaderView 但是 这都不重要,你只要看滚动那部分就可以了!


通过监听滚动的距离,然后显示与隐藏这个View就可以了!就是这么简单
那么我们怎么监听这个滚动的距离呢?

来来来  我们先看看 ListView的

首先我们要设置要悬浮的View 作为HeaderView,当然了 添加已有的HeaderView不影响我们的悬浮的View 但是要知道我们的这个View是在第几个位置

 View header = LayoutInflater.from(this).inflate(R.layout.layout_sticky_list_header, null);
        listView.addHeaderView(header);
        View headerBar = LayoutInflater.from(this).inflate(R.layout.layout_sticky_list_bar, null);
        listView.addHeaderView(headerBar);

然后就是关键了设置 滚动监听

listView.setAdapter(adapter);
listView.setOnScrollListener(onScrollChangeListener);
 private AbsListView.OnScrollListener onScrollChangeListener = new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem > 0) {
                layout_bar.setVisibility(View.VISIBLE);
            } else {
                layout_bar.setVisibility(View.GONE);
            }
        }
    };

ListView的滚动监听 就是通过设置 listView.setOnScrollListener(onScrollChangeListener);

通过监听 firstVisibleItem的位置 来知道 是否到了我们要悬浮的View的位置了,如果到了 那么就显示出来,如果没到 那么就隐藏起来了 

我们这里设置的悬浮的HeaderView是在第二个位置 他的position是1

所以firstVisibleItem必须大于0 才开始显示 如果等于0那么就隐藏起来。然后 就结束了!意不意外 惊不惊喜  完事儿了!哈哈哈

 

那么下面轮到ScrollView了 

有了ListView的经验 我们写ScrollView的时候就简单多了,

分三部步

第一步写一个滚动的监听

第二部写一个滚动位置判断

第三部写一个悬浮View显示不显示!

这就完了啊 妥妥的了啊

 

我们写完各种准备之后 开始设置ScrollView的滚动监听了,但是发现 我曹 没有啊 高版本才有这个功能啊 

那怎么办呢  我们知道ScrollView有一个方法叫做

protected void onScrollChanged(int x, int y, int oldx, int oldy)

这就稳妥了啊 好了 莱斯比个因!

 

首先写一个 ObservableScrollView  extends ScrollView 这方方便我们重写他的onScrollChanged 方法

然偶写一个接口 以及set监听 方便我们 滚动的回调 这个很常见了啊

@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(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
    }

    /**
     * 既然scrollview不能提供滚动监听那么我们自己写滚动的监听
     * @param scrollViewListener
     */
    public void setMyScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

然后设置好我们障眼法!

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.xuhuawei.stickydemo.view.ObservableScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".sticky.StickyScrollViewActivity">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="220dp"
                android:gravity="center"
                android:text="Header"
                android:textSize="18sp" />
            <include
                android:id="@+id/layout_sticky_list_bar"
                layout="@layout/layout_sticky_list_bar" />

            <TextView
                style="@style/text_scroll_style"
                android:text="A" />

            <TextView
                style="@style/text_scroll_style"
                android:text="B" />

            <TextView
                style="@style/text_scroll_style"
                android:text="C" />

            <TextView
                style="@style/text_scroll_style"
                android:text="D" />

            <TextView
                style="@style/text_scroll_style"
                android:text="E" />

            <TextView
                style="@style/text_scroll_style"
                android:text="F" />


            <TextView
                style="@style/text_scroll_style"
                android:text="G" />

            <TextView
                style="@style/text_scroll_style"
                android:text="H" />

            <TextView
                style="@style/text_scroll_style"
                android:text="I" />

            <TextView
                style="@style/text_scroll_style"
                android:text="J" />

            <TextView
                style="@style/text_scroll_style"
                android:text="K" />

            <TextView
                style="@style/text_scroll_style"
                android:text="L" />


        </LinearLayout>
    </com.xuhuawei.stickydemo.view.ObservableScrollView>
<!--这个是为了伪造显示的stickview-->
    <include
        android:visibility="gone"
        android:id="@+id/layout_sticky_list_fake_bar"
        layout="@layout/layout_sticky_list_bar" />
</RelativeLayout>

那个include进来的view就是我们要弄他的View!必须弄他!为啥include 因为为了保证他们一模一样啊!4843!

然后添加好我们的监听回调

scrollView.setMyScrollViewListener(onScrollChangeListener);

一切准备就绪了啊 我们开始放大招了啊 哈哈哈 高潮马上来了啊!亚麻地!哈哈

private ObservableScrollView.ScrollViewListener onScrollChangeListener=new ObservableScrollView.ScrollViewListener(){
        @Override
        public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
            int topPosition=layout_sticky_list_bar.getTop();
            Log.v("xhw","topPosition:"+topPosition+" y:"+y+" oldy:"+oldy);
            if (topPosition>y){
                layout_sticky_list_fake_bar.setVisibility(View.GONE);
            }else{
                layout_sticky_list_fake_bar.setVisibility(View.VISIBLE);
            }
        }
    };

只要涉及到ScrollView的滚动监听 那么就会涉及到子View 的getTop方法,这个Top是距离父类View的距离

而滚动的距离是y,也就是滚动出去的距离是y,

如果自己的位置大于滚动的距离 那就表示  这个view还没到顶端呢

如果自己的位置等于滚动的距离,那么就是表示 自己正在firstVisiblePosition的位置了 

如果自己的位置小于滚动的距离,那么就是表示 自己有一部分view已经进去了 看不到了

 

所以啊 我们知道了 判断的逻辑了 那么显示与隐藏这个悬浮view就简单了啊!

 

最后献上我的源码 :StickyDemo

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值