在這里做了一個折疊列表的效果,先看下效果圖

在這個效果這里我用的是ViewDragHelper來做的。先寫一個類繼承自FramLayout。在這個類的構(gòu)造函數(shù)里創(chuàng)建出ViewDragHelper。
viewDragHelper = ViewDragHelper.create(this, mViewDragHelperCallBack);
在這里ViewDragHelper不能new出來,要去調(diào)用它的create方法,是因為它的構(gòu)造函數(shù)私有化了。在它的兩個參數(shù)里一個是當前的類也就是布局本身,類外一個要傳入一個CallBack。在這個CallBack里面有可以讓內(nèi)部子view可以移動的方法。
private ViewDragHelper.Callback mViewDragHelperCallBack = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
//表示能能讓前面的那個view滑動
return mListView == child;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//控制前面的view滑動的范圍
if (top<=0){
top=0;
}
if (top>= measuredHeight){
top = measuredHeight;
}
return top;
}
//在手指松開的時候,選擇打開還是關(guān)閉
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild == mListView){
if (mListView.getTop()>measuredHeight/2){
// 滾動到菜單的高度(打開)
viewDragHelper.settleCapturedViewAt(0,measuredHeight);
mMenuIsOpen = true;
}else {
mMenuIsOpen = false;
viewDragHelper.settleCapturedViewAt(0,0);
}
invalidate();
}
}
};
在這里我們用到了它的三個方法,第一個是表示滑動的是那個view,第二個是表示讓view垂直滑動,第三個方法表示的事在滑動完之后可以讓view停在那里的方法。當定義好這個自定義view之后,我們?nèi)懳覀兊牟季?/p>
<?xml version="1.0" encoding="utf-8"?>
<com.example.myday14.MyVerticalListView 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"
android:id="@+id/mvLv"
tools:context="com.example.myday14.MainActivity">
<TextView
android:id="@+id/tv_change"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="后面" />
<com.example.myday14.MyListView
android:id="@+id/m_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#999999"
android:gravity="center"
/>
</com.example.myday14.MyVerticalListView>
寫完之后我們在我們的代碼里面給listview設置數(shù)據(jù)之后,就可以看到效果了。但是這個時候滑動還是有問題的,當我們滑動到后面這個view的高度時,向上滑動listview我們會發(fā)現(xiàn)listview不能回到開始的位置了,那是因為在向上滑動的時候,listview的滑動事件將,我們的自定義view的事件給攔截了,所以我們在我們的自定義view的onInterceptTouchEvent里面要處理這個事件,當我們抬起手指的時候,發(fā)現(xiàn)我們的菜單也就是后面的view全部顯示出來的時候,我們要攔截listview的事件,而去相應父view也就是我們定義的view的事件
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//拿到按下時的y位置
mOldY = event.getY();
viewDragHelper.processTouchEvent(event);
break;
case MotionEvent.ACTION_MOVE:
mMoveY = event.getY();
if ((mMoveY-mOldY)>0 && !canChildScrollUp()){
return true;
}
// 菜單打開要攔截
if (mMenuIsOpen) {
return true;
}
break;
}
return super.onInterceptHoverEvent(event);
}
我們定義了一個mMenuIsOpen來表示菜單是否打開,打開的時候我們就去返回true。
代碼放到Github了
https://github.com/chenzhikaizg/MyListView