本文主要是介绍仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
先看效果
分别是我的效果和今日头条的效果:
以上效果包括:
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_viewpublic 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***************************************/@Overridepublic 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;//计算移动后的paddingTopint 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 (
这篇关于仿今日头条下拉出现SearchBar,再下拉刷新效果,SearchListView实现以及原理讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!