Android 抽屉式 ListView实现
最近项目需求,要在ListView的顶部加一个抽屉的区域,按住ListView滑动的时候下拉出这个区域,效果类似于QQ通讯录的联系人Tab中下拉出现收藏的联系人。 这里的实现和QQ通讯录略有不同,借鉴了网上流传很广的下拉刷新的Demo。在此基础上修改了部分代码,重新进行了封装。最核心的判断位移的代码由于太多,所以没有贴出来,需要的朋友可以去下载附件,无毒无公害。 具体的实现思路如下: 1、新建一个类继承ListView,并实现OnScrollListener接口,重写onTouchEvent方法,考虑到封装HeadView区域,因此还对外提供了setHeadView和getHeadView,其实本来是想写成一个属性,将来用的时候可以直接在布局xml里面实现,但由于对这块不熟悉,不知道什么时候能改造完,所以先放出现在的实现。 2、主要位移变化的状态标示,在这里有7个状态
private static final int STATE_IDLE = 0;//初始状态 private static final int STATE_PULL = 1;//从初始向下拉动的状态 private static final int STATE_HOLD = 2;//固定显示整个Head的状态 private static final int STATE_ROLLBACK = 3;//收回这个Head的状态 private static final int STATE_RELEASE_To_HOLD = 4;//向下拉,并且已经拉过HeadView的高度,松手可以显示整个HeadView private static final int STATE_HOLD_RELEASE_To_HOLD = 5;//从固定Head还是向下拉,松手后还是显示固定的Head private static final int STATE_RELEASE_To_ROLLBACK = 6;//向上推动ListView,松手后整个Head消失 private static final int STATE_DONE = 7;//完成状态,和Idle状态类似
这里每个状态对应滑动的位置变化,这里的归纳有一些随意了,不是很好。大家有时间可以帮忙改进一下。 3、重写onTouchEvent方法,在ACTION_DOWN、ACTION_UP、ACTION_MOVE里分别处理。 (1)ACTION_DOWN里面记录按下的位置,并标记开始滑动 (2)ACTION_MOVE中对滑动进行处理,分别为从初始状态开始滑动、滑过Head高度继续向下滑动、滑过Head高度又向上滑动收回。从固定状态向上、向下滑动。 (3)ACTION_UP中处理手指离开屏幕时要做的工作,对应上面的几种情况。分别为固定显示全部内容、收回Head区域等。 4、处理Head区域的方法,对应几种需要改变显示的状态。
private void changeHeaderViewByState() { switch (mState) { case STATE_RELEASE_To_HOLD: tipsTextview.setText("松开固定显示"); case STATE_HOLD: mHeadView.setPadding(0, 0 * mHeadContentHeight, 0, 0); progressBar.setVisibility(View.GONE); arrowImageView.setImageResource(R.drawable.arrow); lastUpdatedTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.startAnimation(animation); tipsTextview.setText("显示全部Head"); break; case STATE_PULL: progressBar.setVisibility(View.GONE); tipsTextview.setVisibility(View.VISIBLE); lastUpdatedTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.setVisibility(View.VISIBLE); // 是由RELEASE_To_REFRESH状态转变来的 tipsTextview.setText("下拉显示全部"); break; case STATE_DONE: mHeadView.setPadding(0, 0 * mHeadContentHeight, 0, 0); // headView.setVisibility(View.INVISIBLE); progressBar.setVisibility(View.GONE); arrowImageView.clearAnimation(); arrowImageView.setImageResource(R.drawable.arrow); tipsTextview.setText("下拉刷新"); lastUpdatedTextView.setVisibility(View.VISIBLE); break; case STATE_ROLLBACK: mHeadView.setPadding(0, -1 * mHeadContentHeight, 0, 0); // headView.setVisibility(View.INVISIBLE); progressBar.setVisibility(View.GONE); arrowImageView.clearAnimation(); arrowImageView.setImageResource(R.drawable.arrow); tipsTextview.setText("收回HeadView"); lastUpdatedTextView.setVisibility(View.VISIBLE); mState = STATE_IDLE; break; } }
头一次写博客分享经验,文字组织的有点乱,很多排版的问题也弄得我头大,大家将就着看,我慢慢研究下怎么能看着更舒服一点。这里感谢下分享下拉刷新的兄弟,我实在忘记了是从哪里下到这个demo的了,不好意思了兄弟,看到麻烦跟我说一声。还有感谢bywyu为我提供的思路。
最后附上之前的下拉刷新代码和我修改过的代码,因为我这里的需求是添加一个顶部布局,所以对外提供了一个接口,setHeadView,而不是写死在控件里面。
我修改过的抽屉式ListView
https://files.cnblogs.com/jianghao/CustomListView.zip
原本的下拉刷新Demo
https://files.cnblogs.com/jianghao/%E4%B8%8B%E6%8B%89%E5%88%B7%E6%96%B0%EF%BC%88%E8%87%AA%E5%AE%9A%E4%B9%89listview%EF%BC%89CustomListView.zip
转载请注明转自http://www.cnblogs.com/jianghao/archive/2012/09/17/2689803.html,谢谢。
之前写的有些问题,后来又修改了一下,附上最新源码: