多個Listview瀑布流效果

多個Listview瀑布流效果

效果展示

原理解釋

自定義MyLinearLayout,繼承至LinearLayout,在佈局文件中,將3個listview放置在MyLinearLayout中。
重寫MyLinearLayout中的onInterceptTouchEvent方法,返回true,打斷向listview傳遞的觸摸事件。
重寫onTouchEvent方法,根據觸摸位置,將觸摸事件通過調用子view的dispatchTouchEvent方法,傳遞給相應位置的listview。
listview接受到觸摸事件後就可以自行處理相關的滑動邏輯。

代碼實現

界面佈局


    <jamffy.example.waterfalllistview.MyLinearLayout xmlns:android="http:// schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="jamffy.example.waterfalllistview.MainActivity" >

    <ListView
        android:id="@+id/lv1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:divider="@null"
        android:dividerHeight="5dp"
        android:scrollbars="none" >
    </ListView>

    <ListView
        android:id="@+id/lv2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:divider="@null"
        android:dividerHeight="5dp"
        android:scrollbars="none" >
    </ListView>

    <ListView
        android:id="@+id/lv3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:divider="@null"
        android:dividerHeight="5dp"
        android:scrollbars="none" >
    </ListView>

    </jamffy.example.waterfalllistview.MyLinearLayout>

自定義控件


    /**
     * @author tmac 如果不做處理MyLinearLayout中的子view能自行處理touch事件。
     *         現在我希望當我在屏幕中間上方拖動時,整個屏幕的子view一起向上拖動,
     *         這是就需要在滿足條件時,中斷該touch事件,交給MyLinearLayout這個父view來處理。
     *         先中斷所有子view的touch事件,然後根據觸摸的位置,有父view把點擊事件分發給相應的子view。
     *         在分發之前需要給touch事件的對象event重新設置位置,因爲子view的座標系與父view是不同的。
     */

    // 這個類專門爲三個子listview服務。
    public class MyLinearLayout extends LinearLayout {

    public MyLinearLayout(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    // 返回true中斷點擊事件
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    // 用分發的方式決定哪個子view可以收到點擊事件
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int count = getChildCount();
        // 每個子view的寬度
        int width = getWidth() / count;
        int height = getHeight();

        // 當前觸摸的位置
        int currX = (int) event.getX();
        int currY = (int) event.getY();
        // 判斷位置
        if (currX < width) { // 處理最左邊的邏輯
            // 在分發之前需要給touch事件的對象event重新設置位置,因爲子view的座標系與父view是不同的。
            event.setLocation(width / 2, currY);
            getChildAt(0).dispatchTouchEvent(event);
            return true;
        } else if (currX < 2 * width) { // 處理中間的邏輯
            if (currY > height / 2) { // 如果在下方,只移動中間的子view
                event.setLocation(width / 2, currY);
                getChildAt(1).dispatchTouchEvent(event);
                return true;
            } else {// 如果在上方,拖動三個view
                event.setLocation(width, currY);
            // 同時把touch事件分發給三個子view
                for(int i=0;i<count;i++){
                    getChildAt(i).dispatchTouchEvent(event);
                }
                return true;
            }

        } else if (currX < 3 * width) { // 處理最右邊的邏輯
            event.setLocation(width / 2, currY);
            getChildAt(2).dispatchTouchEvent(event);
            return true;

        }

        return true;
    }

}

完整代碼

github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章