自定義View折疊列表

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

在這個效果這里我用的是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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容