多個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是不同的。
*/
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int count = getChildCount();
int width = getWidth() / count;
int height = getHeight();
int currX = (int) event.getX();
int currY = (int) event.getY();
if (currX < width) {
event.setLocation(width / 2, currY);
getChildAt(0).dispatchTouchEvent(event);
return true;
} else if (currX < 2 * width) {
if (currY > height / 2) {
event.setLocation(width / 2, currY);
getChildAt(1).dispatchTouchEvent(event);
return true;
} else {
event.setLocation(width, currY);
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