最近項目需求,要在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
http://files.cnblogs.com/jianghao/CustomListView.zip
原本的下拉刷新Demo
http://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,謝謝。
之前寫的有些問題,后來又修改了一下,附上最新源碼: