仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解

本文介绍了如何实现类似今日头条的下拉显示SearchBar并进行刷新的效果。详细讲解了实现原理,包括不同状态的定义,如SEARCH_VIEW_PARTIAL_SHOW、SEARCH_VIEW_FULL_SHOW和REFRESHING,并提供了相应的代码示例。
摘要由CSDN通过智能技术生成

先看效果

分别是我的效果和今日头条的效果:
这里写图片描述这里写图片描述

以上效果包括:
1.如果下拉的高度超过search view的高度的3/4,但是小于head view高度,则松开手时search view自动出现
2.如果下拉的高度小于search view的高度的1/4,则松开手时search view自动回弹消失
3.如果下拉的高度超过head view的总高度,则松手进行刷新
4.刷新完成自动隐藏search view

实现原理讲解

参考了 github开源项目:[https://github.com/vivian8725118/SearchListView ] 但是这个开源调用listview.setOnItemClickListener的时候,下拉出现search view,下拉刷新都响应了onItemClick,这显然是不对的,我在onTouchEvent的Action_Up中进行了修改,以保证能正确响应点击事件。
提示: 这个效果是基于PullToRefreshListView实现的,如果对下拉刷新listview实现不明白的,可以先看这篇博客[http://blog.csdn.net/u010335298/article/details/51098755]
原理讲解
这里写图片描述
如图,将搜索部分的view放进ListView的头view中,在触摸事件中处理search view 的显示和隐藏。

1.我给listview定义了五种状态

    public static final int STATE_NONE  = 0;
    public static final int STATE_PULL_TO_SHOW_SEARCH_VIEW  = 1; // 下拉去展示search_view
    public static final int STATE_PULL_TO_REFRESH = 2; //下拉去刷新
    public static final int STATE_RELEASE_TO_REFRESH = 3; // 释放进行刷新
    public static final int STATE_REFRESHING = 4; // 正在刷新

稍微讲解以下这几种状态:
STATE_PULL_TO_SHOW_SEARCH_VIEW 指的是search view出现了一部分但是没有完全出现的时候
STATE_PULL_TO_REFRESH 指的是search view完全出现,但是head view没有完全出现的时候
STATE_RELEASE_TO_REFRESH 指的是head view完全出现的时候

2.添加search view

 private void initHeaderView() {
        headerView =  View.inflate(getContext(), R.layout.search_header_listview, null);
        searchContainer = (RelativeLayout) headerView.findViewById(R.id.search_container);
        headerTv = (TextView) headerView.findViewById(R.id.tvHead);
        headerView.measure(0, 0); // 系统会帮我们测量出headerView的高度
        headerHeight = refreshHeight = headerView.getMeasuredHeight();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        headerView.setPadding(0, -headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
        super.addHeaderView(headerView, null, false);
    }

    private void addSearchView() {
        searchView = LayoutInflater.from(getContext()).inflate(R.layout.search_view, null);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        searchContainer.addView(searchView , layoutParams);
        searchContainer.measure(0, 0);
        searchContainerHeight = searchContainer.getMeasuredHeight();
        Log.d("zyr", "--------------------searchContainerHeight :" + searchContainerHeight);
        headerHeight = searchContainerHeight + headerHeight ;
        headerView.setPadding(0, - headerHeight, 0, 0);
        invalidate();
        Log.d("zyr", "--------------------headerHeight :" + headerHeight);
        Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
    }

3.触摸事件的处理:我详细的写了注释

/***************************    Touch***************************************/
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN :
                downY = lastMoveY = (int) ev.getY();
                downX = (int) ev.getX();
                break;
            case MotionEvent.ACTION_MOVE :
                moveY = (int) ev.getY();
                moveDiff = (moveY - lastMoveY)/2 ;
                lastMoveY = moveY ;
                diff = moveY - downY;
                //计算移动后的paddingTop
                int paddingTop =   headerView.getPaddingTop() + moveDiff ;
                // 如果: 第一个可见
                if(getFirstVisiblePosition() == 0 && Math.abs(diff) > 50){
                    switch (state){
                        case STATE_NONE :
                        //当状态是none的时候,向下拉才做处理
                            if(diff > 0){
                                state = STATE_PULL_TO_SHOW_SEARCH_VIEW;
                                headerView.setPadding(0, paddingTop, 0, 0);
                                Log.d("zyr", "--------------paddingTop:" + paddingTop);
                                return true;
                            }
                            break;
                        case STATE_PULL_TO_SHOW_SEARCH_VIEW:
                        case STATE_PULL_TO_REFRESH:
                        case STATE_RELEASE_TO_REFRESH:
                            if (paddingTop >= 0 ) { // 完全显示了.
                                Log.i("zyr", "ACTION_MOVE 松开刷新");
                                state = STATE_RELEASE_TO_REFRESH;
                                refreshHeaderView();
                            } else if (
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值