多个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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏非著名程序员

教你如何用 RecyclerView 做一个好用的轮播图

引子 一般情况下,我们手机 App 上轮播图一般都是几张图来回循环,最多也就10几张,一般都是在10张以内的轮播。所以我们一般可能都是自己写,还有可能用到了别人...

2355
来自专栏Windows Community

Windows 8.1 应用再出发 (WinJS) - 几种新增控件(2)

上篇我们介绍了Windows 8.1 和 WinJS 中新增控件中的 AppBarCommand、BackButton、Hub、ItemContainer,本篇...

3236
来自专栏Python小屋

Python实现计算机屏幕任意区域截图

程序功能与用法:运行后有个主窗体,上面有个按钮,单击后开始截图,鼠标坐标落下开始截图,鼠标左键抬起表示截图结束,然后弹出对话框提示保存截图文件。 本文要点在于P...

9238
来自专栏技术专栏

java thumbnailator 做图片处理

1651
来自专栏Android机动车

一个小彩蛋

今天要介绍的就是大神的 Scalpel,可以实现在手机上 3D 展示届满布局,而且用起来超级简单!

1283
来自专栏三流程序员的挣扎

Android 动画总结(2) - 帧动画

Frame Animation,也叫 Drawable Animation,原理就类似视频快速播放一帧一帧的图片。一般场景下很少使用,工作中遇到的是有时会有背景...

1182
来自专栏Android 技术栈

性能优化之布局优化记录

做开发时间长了之后,收集后台的bug,发现很多都是OOM(Out Of Memory Killer)。性能优化这时候成为了重点,下面是自己项目中布局优化的记录,...

692
来自专栏xx_Cc的学习总结专栏

六天完成一个简单iOS App - 第二天

2925
来自专栏Android机动车

Material Design整理(四)——DrawerLayout

注意:在侧滑菜单区必须设置 android:layout_gravity 这个属性,只要布局中设置了android:layout_gravity,它就是侧滑菜单...

1261
来自专栏非著名程序员

AndroidTShare Weekly No.10

本周热点开源项目 SpinMenu 转动轮盘样式的Fragment切换效果,非常漂亮。 效果图如下: ? 作者:Hitomi 项目开源地址:https://gi...

20810

扫码关注云+社区

领取腾讯云代金券